package com.yx.controller;

import com.yx.common.R;
import com.yx.constatns.AuthConstatns;
import com.yx.constatns.CarConstants;
import com.yx.feign.api.GoodsService;
import com.yx.vo.Car;
import com.yx.vo.Customer;
import com.yx.vo.Goods;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Classname CarController
 * @Date 2021/07/16 17:26
 * @Author by yx
 * @Description TODO:
 */
@Controller
@RequestMapping("/carController")
@Slf4j
public class CarController {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private GoodsService goodsService;


    /**
     * @param car
     * @param session
     * @param response
     * @param anneId
     * @return com.yx.common.R
     * @Author:yx
     * @Date 2021/07/16 18:56
     * @Description: 将商品添加到购物车中
     **/
    @PostMapping("/addCar")
    @ResponseBody
    public R addCar(Car car, HttpSession session, HttpServletResponse response,
                    @CookieValue(name = CarConstants.ANNO_CAR_COOKIE_NAME, defaultValue = "") String anneId) {
        //1.获取当前登录用户,从springSession中获取
        Customer customer = (Customer) session.getAttribute(AuthConstatns.AUTH_SESSION);
        //2.创建一个map和redis绑定
        BoundHashOperations<String, Object, Object> userCarHash = null;
        //3.判断用户是否登录
        if (customer != null) {
            //用户已经登录,获取用户id
            Integer id = customer.getId();
            //将map和redis中的hash结构绑定
            userCarHash = stringRedisTemplate.boundHashOps(CarConstants.USERCARPRE + id);
        } else {
            //用户未登录,需要分配一个uuid,首先判断是否已经有znneId
            if (StringUtils.isEmpty(anneId)) {
                //没有匿名id,分配一个
                anneId = UUID.randomUUID().toString();
                //创建一个cookie
                Cookie cookie = new Cookie(CarConstants.ANNO_CAR_COOKIE_NAME, anneId);
                //设置cookie时间--->7天
                cookie.setMaxAge(60 * 60 * 24 * 7);
                //跨域
                cookie.setPath("/");
                //将cookie存入浏览器
                response.addCookie(cookie);
            }
            //绑定
            userCarHash = stringRedisTemplate.boundHashOps(CarConstants.USERCARPRE + anneId);
        }
        userCarHash.put(car.getGid().toString(), car.getSum().toString());
        log.debug("{}", car);
        return R.success();
    }

    @GetMapping("/mergeCar/{uid}/{annoId}")
    @ResponseBody
    public R mergeCar(@PathVariable("uid") Integer uid, @PathVariable String annoId) {

        //绑定redis中的hash结构
        // hash结构数据:car:id  gid    sum
        BoundHashOperations<String, Object, Object> annoIdCarMap = stringRedisTemplate.boundHashOps(CarConstants.USERCARPRE + annoId);
        BoundHashOperations<String, Object, Object> userIdCarMap = stringRedisTemplate.boundHashOps(CarConstants.USERCARPRE + uid);
        //获取匿名id的购物车集合
        Map<Object, Object> annoCarMap = annoIdCarMap.entries();
        //获取购物车
        Set<Map.Entry<Object, Object>> entries = annoCarMap.entrySet();
        //获取商品属性
        for (Map.Entry<Object, Object> entry : entries) {
            Object key = entry.getKey();
            Object value = entry.getValue();

            //判断用户id的购物车是否有此商品,有数量改变,没有直接添加至用户购物车
            if (userIdCarMap.hasKey(key)) {
                Integer uNum = Integer.valueOf(userIdCarMap.get(key).toString());
                Integer aNum = Integer.valueOf(value.toString());
                value = uNum + aNum;
            }
            //将匿名id用户的购物车商品数据添加至用户购物车
            userIdCarMap.put(key, value);
        }

        //清空annoId的购物车数据
        stringRedisTemplate.delete(CarConstants.USERCARPRE + annoId);

        return R.success();
    }


    @GetMapping("/getUserCarList")
    public String getUserCarList(HttpSession session, ModelMap modelMap, @CookieValue(name = CarConstants.ANNO_CAR_COOKIE_NAME, defaultValue = "", required = false) String annoId) {

        //1.获取当前登录的用户
        Customer customer = (Customer) session.getAttribute(AuthConstatns.AUTH_SESSION);
        //查询购物车数据
        //绑定hash结构
        BoundHashOperations<String, Object, Object> carMap = null;
        if (customer != null) {
            //用户登录
            carMap = stringRedisTemplate.boundHashOps(CarConstants.USERCARPRE + customer.getId());
        } else {
            //排除用户不登陆,没把商品加入购物车,就直接点击购物车的行为
            if (!StringUtils.isEmpty(annoId)) {
                //用户未登录,查询匿名id的购物车
                carMap = stringRedisTemplate.boundHashOps(CarConstants.USERCARPRE + annoId);
            }
        }

        // 3.封装查询到的购物车数据--->redis中的hash结构:car:id;gid;sum 购物车+用户id;商品id;商品数量
        List<Car> carList = new ArrayList<>();

        Map<Object, Object> entries = carMap.entries();
        for (Map.Entry<Object, Object> entry : entries.entrySet()) {
            //获取键值
            Object key = entry.getKey();
            Object value = entry.getValue();
            //封装
            Car car = new Car();
            Integer gid = Integer.valueOf(key.toString());
            Integer sum = Integer.valueOf(value.toString());
            //根据商品id查询商品信息
            Goods goods = goodsService.getGoodById(gid);
            //填充数据
            car.setGid(gid);
            car.setSum(sum);
            car.setGoods(goods);
            BigDecimal subTotal = goods.getGprice().multiply(BigDecimal.valueOf(sum));
            car.setSubTotal(subTotal);


            //将单个商品的购物车信息添加到购物车集合中.
            carList.add(car);
        }

        modelMap.put("carList", carList);

        return "carList";
    }

    @PostMapping("/updateCar")
    @ResponseBody
    public R updateCar(String gid, String type, HttpSession session,
                       @CookieValue(name = CarConstants.ANNO_CAR_COOKIE_NAME, defaultValue = "") String annoId) {
        //1.获取登录的用户id
        Customer customer = (Customer) session.getAttribute(AuthConstatns.AUTH_SESSION);

        BoundHashOperations<String, Object, Object> carMap = null;
        if (customer != null) {
            //用户登录
            carMap = stringRedisTemplate.boundHashOps(CarConstants.USERCARPRE + customer.getId());
        } else {
            //排除用户不登陆,没把商品加入购物车,就直接点击购物车的行为
            if (!StringUtils.isEmpty(annoId)) {
                //用户未登录,查询匿名id的购物车
                carMap = stringRedisTemplate.boundHashOps(CarConstants.USERCARPRE + annoId);
            }
        }

        System.out.println("商品id: " + gid);
        System.out.println("商品id: " + type);
//        System.out.println("商品数量: "+sum);

        // 从前台获取的是实时商品数量,直接把redis中的数据覆盖即可完成数据的更新
//        carMap.put(gid, sum);

        switch (type) {
            case CarConstants.CAR_INCR:
                // 自增
                carMap.increment(gid, 1);
                break;
            case CarConstants.CAR_DECR:
                Integer num = Integer.parseInt(carMap.get(gid).toString());
//                System.out.println(--num);
                if (--num <= 0) {
                    //商品总数小于0,删除该商品
                    carMap.delete(gid);
                    break;
                }
                carMap.put(gid, (--num) + "");
                break;
        }

        return R.success();
    }

    @GetMapping("/deleteCar/{gid}")
    public String deleteCar(@PathVariable String gid, HttpSession session,
                            @CookieValue(name = CarConstants.ANNO_CAR_COOKIE_NAME, defaultValue = "") String annoId) {
        //1.获取登录的用户id
        Customer customer = (Customer) session.getAttribute(AuthConstatns.AUTH_SESSION);

        BoundHashOperations<String, Object, Object> carMap = null;
        if (customer != null) {
            //用户登录
            carMap = stringRedisTemplate.boundHashOps(CarConstants.USERCARPRE + customer.getId());
        } else {
            //排除用户不登陆,没把商品加入购物车,就直接点击购物车的行为
            if (!StringUtils.isEmpty(annoId)) {
                //用户未登录,查询匿名id的购物车
                carMap = stringRedisTemplate.boundHashOps(CarConstants.USERCARPRE + annoId);
            }
        }
        System.out.println("商品id: " + gid);
        carMap.delete(gid);
        return "redirect:/carController/getUserCarList";

    }

    /*
     * order服务调用控制层方法
     * */
    @RequestMapping("/getCarListByUidAndGid")
    @ResponseBody
    public Map<String, Object> getCarListByUidAndGid(@RequestParam("uid") Integer uid, @RequestParam("gidArray") List<String> gidArray) {
        Map<String, Object> map = getCarList(uid, gidArray);
        return map;
    }

    @RequestMapping("/getCarListByUid/{uid}")
    @ResponseBody
    public Map<String, Object> getCarListByUid(@PathVariable Integer uid) {
        Map<String, Object> map = getCarList(uid, null);
        return map;

    }


    private Map<String, Object> getCarList(Integer uid, List<String> gidArray) {
        List<Car> carList = new ArrayList<>();
        BigDecimal totalPrice = new BigDecimal(0.0);
        //查询购物车
        BoundHashOperations<String, Object, Object> carMap = stringRedisTemplate.boundHashOps(CarConstants.USERCARPRE + uid);
        //判断用户是否勾选 判断是有顺序的,当存在集合未实例化直接赋值为空情况时,应该先判空,再判断集合是否有值
//        if (gidArray.size() > 0 && gidArray != null) {
        if (gidArray != null && gidArray.size() > 0) {
            //勾选了
            for (String gid : gidArray) {
                String sum = (String) carMap.get(gid); //存储的hash结构中,value为sum,key为gid
                //封装
                toCarObject(carList, gid, sum);
            }
        } else {
            Set<Map.Entry<Object, Object>> entries = carMap.entries().entrySet();
            for (Map.Entry<Object, Object> entry : entries) {
                String key = (String) entry.getKey();
                String value = (String) entry.getValue();
                toCarObject(carList, key, value);
            }
        }

        //计算总计
        for (Car car : carList) {
            totalPrice = totalPrice.add(car.getSubTotal());
        }

        //视图
        Map<String, Object> map = new HashMap<>();
        map.put("totalPrice", totalPrice);
        map.put("carList", carList);
        return map;

    }

    private void toCarObject(List<Car> carList, String key, String value) {
        //创建对象
        Car car = new Car();
        //类型转换
        int gid = Integer.parseInt(key);
        int sum = Integer.parseInt(value);
        //查询商品信息
        Goods goods = goodsService.getGoodById(gid);
        //封装
        car.setGid(gid);
        car.setGoods(goods);
        car.setSum(sum);
        //计算suTotal
        BigDecimal subTotal = goods.getGprice().multiply(BigDecimal.valueOf(sum));
        car.setSubTotal(subTotal);
        carList.add(car);
    }

}
